﻿//Created by Action Script Viewer - http://www.buraks.com/asv
package Classes.effects.Particle {
    import Engine.Classes.*;
    import Engine.Events.*;
    import flash.display.*;
    import flash.geom.*;
    import Engine.Helpers.*;
    import flash.utils.*;
    import Classes.*;
    import Classes.effects.*;
    import Engine.*;

    public class ParticleEffect extends MapResourceEffect {

        private static const MAX_SCALE:Number = 300;

        protected var m_effectName:String;
        protected var m_itemImage:ItemImage;
        protected var m_originalFPS:Number;
        protected var m_particleContainer:Sprite;
        protected var m_itemImageLoaded:Boolean;
        protected var m_activeParticles:Array;
        protected var m_doneParticles:Array;
        protected var m_isActive:Boolean;
        protected var m_isRunning:Boolean;
        protected var m_lastTime:Number;
        protected var m_lastSpawnTime:Number;
        public var spawnPeriod:Number;
        public var minVel:Number;
        public var maxVel:Number;
        public var minAngle:Number;
        public var maxAngle:Number;
        public var minDuration:Number;
        public var maxDuration:Number;
        public var minRotationVel:Number;
        public var maxRotationVel:Number;
        public var startAlpha:Number;
        public var endAlpha:Number;
        public var minStartScale:Number;
        public var maxStartScale:Number;
        public var endScale:Number;
        public var initRotRandomness:Number;
        public var loopParticleAnimation:Boolean;

        public function ParticleEffect(_arg1:MapResource, _arg2:String){
            super(_arg1, 30);
            this.m_activeParticles = new Array();
            this.m_doneParticles = new Array();
            this.m_isActive = true;
            this.m_lastTime = getTimer();
            this.m_lastSpawnTime = getTimer();
            this.m_itemImageLoaded = false;
            this.m_isRunning = true;
            this.m_particleContainer = new Sprite();
            var _local3:Sprite = this.getAttachParent();
            if (_local3){
                _local3.addChild(this.m_particleContainer);
            };
            this.m_effectName = _arg2;
            this.spawnPeriod = 0.5;
            this.minVel = 0;
            this.maxVel = 100;
            this.minAngle = 0;
            this.maxAngle = 360;
            this.minDuration = 0.5;
            this.maxDuration = 1;
            this.minRotationVel = -500;
            this.maxRotationVel = 500;
            this.startAlpha = 1;
            this.endAlpha = 0;
            this.minStartScale = 1;
            this.maxStartScale = 1;
            this.endScale = 1;
            this.initRotRandomness = 0;
            this.loopParticleAnimation = true;
        }
        override public function animate(_arg1:uint):Boolean{
            if (!this.m_isActive){
                return (this.m_isActive);
            };
            if (!this.m_itemImage){
                this.loadAnimationEffect();
            };
            if (!this.m_itemImageLoaded){
                return (this.m_isActive);
            };
            var _local2:Number = getTimer();
            var _local3:Number = ((_local2 - this.m_lastTime) / 1000);
            this.m_lastTime = _local2;
            this.updateExistingParticles(_local3);
            this.cleanupDeadParticles();
            this.spawnNewParticles(_local3);
            return (this.m_isActive);
        }
        protected function updateExistingParticles(_arg1:Number):void{
            var _local2:Particle;
            var _local3:Number;
            var _local4:Number;
            for each (_local2 in this.m_activeParticles) {
                _local3 = ((_local2.activeTime = (_local2.activeTime + _arg1)) / _local2.duration);
                if (_local3 > 1){
                    _local2.displayObject.visible = false;
                    _local2.done = true;
                } else {
                    this.updateParticleAnimation(_local2, _arg1);
                    _local4 = (1 - _local3);
                    _local2.displayObject.x = (_local2.displayObject.x + ((_local2.vel.x * _arg1) * _local4));
                    _local2.displayObject.y = (_local2.displayObject.y + ((_local2.vel.y * _arg1) * _local4));
                    _local2.displayObject.rotation = (_local2.displayObject.rotation + (_local2.deltaRotation * _arg1));
                    _local2.displayObject.alpha = (((this.endAlpha - this.startAlpha) * _local3) + this.startAlpha);
                    _local2.displayObject.scaleX = (_local2.displayObject.scaleY = (((_local2.endScale - _local2.startScale) * _local3) + _local2.startScale));
                };
            };
        }
        protected function cleanupDeadParticles():void{
            var _local2:Particle;
            var _local1:Number = (this.m_activeParticles.length - 1);
            while (_local1 > -1) {
                if (this.m_activeParticles[_local1].done){
                    this.m_doneParticles.push(this.m_activeParticles.splice(_local1, 1)[0]);
                };
                _local1--;
            };
            if (((!(this.m_isRunning)) && ((this.m_activeParticles.length < 1)))){
                for each (_local2 in this.m_doneParticles) {
                    if (((_local2.displayObject) && (_local2.displayObject.parent))){
                        _local2.displayObject.parent.removeChild(_local2.displayObject);
                        _local2.displayObject = null;
                    };
                };
                this.m_doneParticles.splice(0, this.m_doneParticles.length);
            };
        }
        protected function spawnNewParticles(_arg1:Number):void{
            var _local2:Vector2;
            var _local3:Number;
            var _local4:int;
            var _local5:Particle;
            if (((this.m_isActive) && (this.m_isRunning))){
                _local2 = this.getTargetPos();
                _local3 = this.getNumNewParticles(_arg1);
                if (_local3 > 0){
                    this.m_lastSpawnTime = getTimer();
                    _local4 = 0;
                    while (_local4 < _local3) {
                        if (this.m_doneParticles.length > 0){
                            _local5 = this.m_doneParticles.splice(0, 1)[0];
                        } else {
                            _local5 = new Particle();
                            this.attachNewParticle(_local5);
                        };
                        this.initParticle(_local5, _local2);
                        this.m_activeParticles.push(_local5);
                        _local4++;
                    };
                };
            } else {
                this.m_lastSpawnTime = getTimer();
            };
        }
        protected function initParticle(_arg1:Particle, _arg2:Vector2):void{
            var _local3:DisplayObject = m_mapResource.displayObject;
            var _local4:DisplayObject = m_mapResource.content;
            _arg1.lastFrame = -1;
            var _local5:Number = (this.maxVel - this.minVel);
            var _local6:Number = (this.maxAngle - this.minAngle);
            var _local7:Number = (this.maxDuration - this.minDuration);
            var _local8:Number = (this.maxRotationVel - this.minRotationVel);
            var _local9:Number = (this.maxStartScale - this.minStartScale);
            var _local10:Number = ((((_local6 * Math.random()) + this.minAngle) * Math.PI) / 180);
            var _local11:Vector2 = new Vector2(Math.cos(_local10), Math.sin(_local10));
            var _local12:Number = ((_local5 * Math.random()) + this.minVel);
            _arg1.vel = new Vector2((_local11.x * _local12), (_local11.y * _local12));
            _arg1.startScale = Math.min(MAX_SCALE, (((_local9 * Math.random()) + this.minStartScale) * _local3.scaleX));
            _arg1.endScale = Math.min(MAX_SCALE, (this.endScale * _local3.scaleX));
            _arg1.deltaRotation = ((_local8 * Math.random()) + this.minRotationVel);
            _arg1.duration = (this.minDuration + (_local7 * Math.random()));
            _arg1.activeTime = 0;
            _arg1.done = false;
            _arg1.displayObject.x = _arg2.x;
            _arg1.displayObject.y = _arg2.y;
            _arg1.displayObject.rotation = MathUtil.randomWobble(0, Math.min(this.initRotRandomness, 360));
            _arg1.displayObject.alpha = this.startAlpha;
            _arg1.displayObject.visible = false;
            _arg1.displayObject.scaleX = (_arg1.displayObject.scaleY = _arg1.startScale);
        }
        public function attachNewParticle(_arg1:Particle):void{
            if (((!(this.m_itemImage)) || (!(this.m_itemImage.getInstance())))){
                return;
            };
            this.m_itemImageLoaded = true;
            var _local2:DisplayObject = (this.m_itemImage.getInstance().image as DisplayObject);
            _local2.x = (_local2.x - (_local2.width / 2));
            _local2.y = (_local2.y - (_local2.height / 2));
            _arg1.displayObject = new Sprite();
            (_arg1.displayObject as Sprite).addChild(_local2);
            (_arg1.displayObject as Sprite).mouseEnabled = false;
            (_arg1.displayObject as Sprite).mouseChildren = false;
            if ((_local2 is AnimatedBitmap)){
                _arg1.animation = (_local2 as AnimatedBitmap);
            };
            if (this.m_particleContainer){
                this.m_particleContainer.addChild(_arg1.displayObject);
            };
        }
        protected function updateParticleAnimation(_arg1:Particle, _arg2:Number):void{
            var _local3:AnimatedBitmap;
            var _local4:Number;
            var _local5:int;
            var _local6:Boolean;
            if (_arg1.animation){
                _local3 = _arg1.animation;
                if (((!(_local3.isPlaying)) && ((_arg1.lastFrame < 0)))){
                    _local3.reset();
                };
                if (!this.loopParticleAnimation){
                    _local4 = (1000 / this.m_originalFPS);
                    _local5 = Math.ceil(((_arg2 * 1000) / _local4));
                    _local6 = ((_local3.currentFrame + _local5) > (_local3.numFrames - 1));
                    _local6 = ((_local6) || ((((_local3.currentFrame < _arg1.lastFrame)) || ((_local3.currentFrame == (_local3.numFrames - 1))))));
                    if (((_local3.isPlaying) && (_local6))){
                        _local3.stop();
                    } else {
                        _arg1.lastFrame = _local3.currentFrame;
                    };
                };
                _local3.onUpdate(_arg2);
            };
            _arg1.displayObject.visible = true;
        }
        protected function getTargetPos():Vector2{
            var _local1:DisplayObject = m_mapResource.displayObject;
            var _local2:DisplayObject = m_mapResource.content;
            var _local3:Vector2 = this.getTargetOffset();
            var _local4:Number = (_local2.x + _local3.x);
            var _local5:Number = (_local2.y + _local3.y);
            var _local6:Point = _local2.parent.localToGlobal(new Point(_local4, _local5));
            var _local7:Point = this.m_particleContainer.globalToLocal(_local6);
            _local4 = _local7.x;
            _local5 = _local7.y;
            return (new Vector2(_local4, _local5));
        }
        protected function getNumNewParticles(_arg1:Number):int{
            var _local2:Number = ((getTimer() - this.m_lastSpawnTime) / 1000);
            return (Math.floor((_local2 / this.spawnPeriod)));
        }
        protected function getTargetOffset():Vector2{
            var _local1:DisplayObject = m_mapResource.content;
            return (new Vector2((_local1.width / 2), (_local1.height / 2)));
        }
        public function setIsRunning(_arg1:Boolean):void{
            this.m_isRunning = _arg1;
        }
        public function getIsRunning():Boolean{
            return (this.m_isRunning);
        }
        protected function getAttachParent():Sprite{
            if (m_mapResource.getDisplayObject().parent){
                return ((m_mapResource.getDisplayObject().parent as Sprite));
            };
            return (null);
        }
        override public function cleanUp():void{
            var _local1:Particle;
            var _local2:Particle;
            for each (_local1 in this.m_activeParticles) {
                if (((_local1.displayObject) && (_local1.displayObject.parent))){
                    _local1.displayObject.parent.removeChild(_local1.displayObject);
                    _local1.displayObject = null;
                };
            };
            for each (_local2 in this.m_doneParticles) {
                if (((_local2.displayObject) && (_local2.displayObject.parent))){
                    _local2.displayObject.parent.removeChild(_local2.displayObject);
                    _local2.displayObject = null;
                };
            };
            this.m_activeParticles = null;
            this.m_doneParticles = null;
            if (((this.m_particleContainer) && (this.m_particleContainer.parent))){
                this.m_particleContainer.parent.removeChild(this.m_particleContainer);
            };
            if (this.m_itemImage){
                this.m_itemImage.removeEventListener(LoaderEvent.LOADED, this.onItemImageLoaded);
                this.m_itemImage = null;
            };
            this.m_isActive = false;
        }
        protected function loadAnimationEffect():void{
            var _local2:XML;
            var _local3:XML;
            var _local1:Boolean = ((((m_mapResource.content) && (m_mapResource.getItemImage()))) && (!(m_mapResource.isCurrentImageLoading())));
            if (((_local1) && (!(this.m_itemImage)))){
                _local2 = Global.gameSettings.getEffectByName(this.m_effectName);
                _local3 = _local2.image[0];
                this.m_originalFPS = ((_local3.@fps) || (1));
                this.m_itemImage = new ItemImage(_local3);
                this.m_itemImage.addEventListener(LoaderEvent.LOADED, this.onItemImageLoaded, false, 0, true);
                this.m_itemImage.load();
            };
        }
        protected function onItemImageLoaded(_arg1:LoaderEvent):void{
            if (_arg1.target == this.m_itemImage){
                this.m_itemImage.removeEventListener(LoaderEvent.LOADED, this.onItemImageLoaded);
                this.m_itemImageLoaded = true;
            };
        }
        public function isComplete():Boolean{
            return (!(this.m_isActive));
        }

    }
}//package Classes.effects.Particle 
